<template>
  <div style="width: 100%; height: 100%"></div>
</template>

<script>
import {
  Scene,
  PerspectiveCamera,
  WebGLRenderer,
  MeshBasicMaterial,
  SpotLight,
  BoxGeometry,
  PlaneGeometry,
  Vector3,
  Mesh
} from 'three'
import Detector from 'three/examples/js/Detector'
import dat from 'three/examples/js/libs/dat.gui.min'
export default {
  data() {
    return {
      scene: null,
      camera: null,
      renderer: null,
      ele: null,
      width: 0,
      height:0,
      group: null,
      gui: null,
      controls: new function () {
        this.rotationX = 0.01
        this.rotationY = 0.01
        this.rotationZ = 0.01
      }
    }
  },
  mounted() {
    this.ele = this.$el
    this.width = this.$el.clientWidth
    this.height = this.$el.clientHeight

    if (!Detector.webgl) {
      const warning = Detector.getWebGLErrorMessage()
      this.ele.appendChild(warning)
    }
    this.threeStart()
  },
  methods: {
    threeStart () {
      this.addGUI()
      this.initThree()
      this.initScene()
      this.initCamera()
      this.initLight()
      this.addGeometry()
      this.initPlane()
      this.render()
    },
    initThree () {
      this.renderer = new WebGLRenderer({
        antialias : true // 是否弱化锯齿特性，true表示弱化，更消耗cpu
      })
      this.renderer.setSize(this.width, this.height)
      this.ele.appendChild(this.renderer.domElement)
      this.renderer.setClearColor(0xEEEEEE, 1)
      this.renderer.shadowMap.enabled = false
    },
    initCamera () {
      this.camera = new PerspectiveCamera(45, this.width / this.height, 0.1, 1000)
      this.camera.position.set(-40, 40, 40)
      this.camera.lookAt(this.scene.position)
    },
    initScene () {
      this.scene = new Scene()
    },
    initPlane () {
      const groundGeom = new PlaneGeometry(100, 100, 4, 4)
      const groundMesh = new Mesh(groundGeom, new MeshBasicMaterial({
        color: 0x777777
      }))

      groundMesh.rotation.x = -Math.PI / 2
      groundMesh.position.y = -20
      this.scene.add(groundMesh)
    },
    addGeometry () {
      this.group = new Mesh()
      let mats = []
      mats.push(new MeshBasicMaterial({ color: 0x009e60}))
      mats.push(new MeshBasicMaterial({ color: 0x0051ba}))
      mats.push(new MeshBasicMaterial({ color: 0xffd500}))
      mats.push(new MeshBasicMaterial({ color: 0xff5800}))
      mats.push(new MeshBasicMaterial({ color: 0xC41E3A}))
      mats.push(new MeshBasicMaterial({ color: 0xAD34F3}))
      for (let x = 0; x < 3; x++) {
        for (let y = 0; y < 3; y++) {
          for (let z = 0; z < 3; z++) {
            const cubeGeom = new BoxGeometry(2.9, 2.9, 2.9)
            const cube = new Mesh(cubeGeom, mats)
            cube.position.set(x * 3 - 3, y * 3 - 3, z * 3 - 3)

            this.group.add(cube)
          }
        }
      }

      this.group.scale.copy(new Vector3(2,2,2))
      this.scene.add(this.group)
    },
    initLight () {
      const spotLight = new SpotLight(0xffffff)
      spotLight.position.set(-40, 60, -10)
      spotLight.castShadow = true
      this.scene.add(spotLight)
    },
    addGUI () {
      this.gui = new dat.GUI()
      this.gui.add(this.controls, 'rotationX', 0.01, 0.2)
      this.gui.add(this.controls, 'rotationY', 0.01, 0.2)
      this.gui.add(this.controls, 'rotationZ', 0.01, 0.2)
      this.gui.domElement.style.position = 'fixed'
      this.gui.domElement.style.height = '105px'
      this.ele.appendChild(this.gui.domElement)
    },
    render () {
      requestAnimationFrame(this.render)
      this.group.rotation.x += this.controls.rotationX
      this.group.rotation.y += this.controls.rotationY
      this.group.rotation.z += this.controls.rotationZ
      this.renderer.render(this.scene, this.camera)
    }
  }
}
</script>
